<template>
  <el-sub-menu index="4">
    <template #title>工具箱</template>
    <el-menu-item index="4-1" @click="startMeasure('LineString')"> 测量距离 </el-menu-item>
    <el-menu-item index="4-2" @click="startMeasure('Polygon')"> 测量面积 </el-menu-item>
    <el-menu-item index="4-3" @click="clearMeasure"> 关闭测量 </el-menu-item>
    <el-menu-item index="4-4" @click="exportImage"> 导出图片 </el-menu-item>
  </el-sub-menu>

  <!-- 测量结果弹窗 -->
  <div ref="popup" class="ol-popup" v-show="popupVisible">
    <a href="#" class="ol-popup-closer" @click.prevent="clearMeasure">&times;</a>
    <div id="popup-content">{{ popupText }}</div>
  </div>
</template>

<script setup>
import { ref, watch, onBeforeUnmount, nextTick } from 'vue'
import { useMapStore } from '@/stores/mapStore'
import { ElMessage } from 'element-plus'
import { lineString, polygon, length, area, booleanEqual, point } from '@turf/turf'
import { saveAs } from 'file-saver'
// 正确导入方式（ES6 模块）

const mapStore = useMapStore()

// 组件状态
const popup = ref(null)
const measureSource = ref(new window.ol.source.Vector())
const popupText = ref('')
const popupVisible = ref(false)
const popupOverlay = ref(null)
let drawInteraction = null
const isDrawing = ref(false)
let vectorLayer = null  // 改为模块级变量避免重复创建

// 修复1：使用具名函数解决ESC事件泄露
const onEsc = (e) => e.key === 'Escape' && clearMeasure()

// 样式配置
const measureStyle = {
  LineString: new window.ol.style.Style({
    stroke: new window.ol.style.Stroke({ color: 'rgba(255, 0, 0, 0.8)', width: 2 }),
    fill: new window.ol.style.Fill({ color: 'rgba(0,0,0,0)' })
  }),
  Polygon: new window.ol.style.Style({
    stroke: new window.ol.style.Stroke({ color: 'rgba(0, 115, 255, 0.8)', width: 2 }),
    fill: new window.ol.style.Fill({ color: 'rgba(0, 115, 255, 0.2)' })
  })
}

watch(
  () => mapStore.mapInstance,
  (map) => {
    if (map && !vectorLayer) {  // 修复2：确保只创建一次图层
      // 创建测量图层
      vectorLayer = new window.ol.layer.Vector({
        source: measureSource.value,
        style: (feature) => measureStyle[feature.getGeometry().getType()] || new window.ol.style.Style(),
        zIndex: 9999
      })

      // 初始化测量工具
      const initMeasureTools = () => {
        if (!map.getLayers().getArray().includes(vectorLayer)) {
          map.addLayer(vectorLayer)
        }

        // 修复3：弹窗单例化
        if (!popupOverlay.value) {
          popupOverlay.value = new window.ol.Overlay({
            element: popup.value,
            autoPan: true,
            autoPanMargin: 50
          })
          map.addOverlay(popupOverlay.value)
        }
      }
      initMeasureTools()
    }
  },
  { immediate: true }
)

// 格式化测量结果
const formatMeasurement = (value, type) => {
  const formatter = new Intl.NumberFormat('zh-CN', { maximumFractionDigits: 2 })
  if (type === 'length') {
    return value > 1000 ? `${formatter.format(value / 1000)} 公里` : `${formatter.format(value)} 米`
  }
  return value > 1e6 ? `${formatter.format(value / 1e6)} 平方公里` : `${formatter.format(value)} 平方米`
}

// 事件处理函数
const handleDrawStart = () => {
  popupVisible.value = true
  popupText.value = '绘制中...'
}

const handleDrawCursor = (event) => {
  const geometry = event.feature?.getGeometry()
  if (!geometry) return

  const type = geometry.getType()
  const coords = geometry.getCoordinates()
  let measurement = 0

  // 坐标转换函数
  const transformToWGS84 = (coord) => window.ol.proj.transform(coord, 'EPSG:3857', 'EPSG:4326')

  if (type === 'LineString') {
    const line = lineString(coords.map(transformToWGS84))
    measurement = length(line, { units: 'kilometers' }) * 1000
  } else if (type === 'Polygon') {
    const polygonCoords = coords.map(ring => {
      const transformed = ring.map(transformToWGS84)
      if (transformed.length > 0 && !booleanEqual(point(transformed[0]), point(transformed[transformed.length - 1]))) {
        transformed.push(JSON.parse(JSON.stringify(transformed[0])))
      }
      return transformed
    })
    measurement = area(polygon(polygonCoords))
  }

  popupText.value = `${type === 'LineString' ? '距离' : '面积'}: ${formatMeasurement(measurement, type === 'LineString' ? 'length' : 'area')}`
  popupOverlay.value?.setPosition(window.ol.proj.transform(geometry.getLastCoordinate(), 'EPSG:3857', 'EPSG:4326'))  // 修复4：坐标转换
  // 修改坐标转换部分
  // popupOverlay.value?.setPosition(geometry.getLastCoordinate()); // 直接使用地图坐标
}

// 修改handleDrawEnd方法
const handleDrawEnd = (event) => {
  isDrawing.value = false
  try {
    const geometry = event.feature.getGeometry()
    const type = geometry.getType()
    const coords = geometry.getCoordinates()

    // 添加坐标有效性验证
    if (!coords || coords.length === 0) {
      throw new Error('无效的几何图形')
    }

    // 统一使用地图视图坐标系（EPSG:3857）
    const lastCoord = geometry.getLastCoordinate()
    const transformToWGS84 = (coord) => window.ol.proj.transform(coord, 'EPSG:3857', 'EPSG:4326')

    let measurement = 0
    if (type === 'LineString') {
      const line = lineString(coords.map(transformToWGS84))
      measurement = length(line, { units: 'kilometers' }) * 1000
    } else if (type === 'Polygon') {
      const validCoords = coords.map(ring => {
        const closedRing = booleanEqual(point(ring[0]), point(ring[ring.length - 1]))
          ? ring
          : [...ring, ring[0]]
        return closedRing.map(transformToWGS84)
      })
      measurement = area(polygon(validCoords))
    }

    // 强制更新DOM
    nextTick(() => {
      popupText.value = `${type === 'LineString' ? '距离' : '面积'}: ${formatMeasurement(measurement, type === 'LineString' ? 'length' : 'area')
        }`
      popupOverlay.value?.setPosition(lastCoord)  // 直接使用地图坐标
      popupVisible.value = true
    })

  } catch (error) {
    console.error('测量错误:', error)
    ElMessage.error(`测量失败: ${error.message}`)
    clearMeasure()
  }
}

// 测量功能
const startMeasure = (type) => {
  clearMeasure()
  drawInteraction = new window.ol.interaction.Draw({
    source: measureSource.value,
    type: type,
    style: (feature) => measureStyle[feature.getGeometry().getType()]
  })

  drawInteraction.on('drawstart', handleDrawStart)
  drawInteraction.on('drawcursor', handleDrawCursor)
  drawInteraction.on('drawend', handleDrawEnd)
  mapStore.mapInstance.addInteraction(drawInteraction)
  document.addEventListener('keydown', onEsc)
}


// 在clearMeasure中重置状态
const clearMeasure = () => {
  if (drawInteraction) {
    mapStore.mapInstance.removeInteraction(drawInteraction)
    document.removeEventListener('keydown', onEsc)
    drawInteraction = null  // 清除交互
  }
  measureSource.value.clear()

  const interactions = mapStore.mapInstance.getInteractions().getArray()
  interactions.forEach((interaction) => {
    if (interaction instanceof window.ol.interaction.Draw) {
      mapStore.mapInstance.removeInteraction(interaction)
      interaction.dispose()

    }
  })

  // 弹窗渐隐效果
  popupText.value = '测量已关闭'
  setTimeout(() => {
    popupVisible.value = false
    popupText.value = ''
  }, 1000) // 1秒后关闭弹窗
}



const map = mapStore.mapInstance

function exportImage() {
  map.once('postcompose', function (event) {
    var canvas = event.context.canvas

    canvas.toBlob(function (blob) {
      saveAs(blob, 'map.png')
    })
  })
  map.renderSync()
}

// // 修复5：处理导出图片跨域问题
// const exportImage = async () => {
//   try {
//     const canvas = mapStore.mapInstance.getViewport().querySelector('canvas')
//     if (!canvas) throw new Error('无法获取地图画布')

//     // 设置跨域属性
//     mapStore.mapInstance.getLayers().forEach(layer => {
//       const source = layer.getSource()
//       if (source instanceof window.ol.source.ImageWMS) {
//         source.setImageLoadFunction((image, src) => {
//           image.getImage().crossOrigin = 'anonymous'
//           image.setUrl(src)
//         })
//       }
//     })

//     canvas.toBlob((blob) => {
//       if (!blob) {
//         ElMessage.error('导出失败：存在跨域资源')
//         return
//       }
//       const url = URL.createObjectURL(blob)
//       ElMessageBox.confirm('右键另存为图片', '导出地图', {
//         dangerouslyUseHTMLString: true,
//         message: `<img src="${url}" style="max-width:80vw; max-height:80vh;">`
//       })
//     }, 'image/png', 1.0)
//   } catch (error) {
//     ElMessage.error(error.message || '导出失败')
//   }
// }

// 清理资源
onBeforeUnmount(() => {
  clearMeasure()

  if (vectorLayer) {
    mapStore.mapInstance?.removeLayer(vectorLayer)
    vectorLayer = null
  }
  popupOverlay.value?.dispose()
})
</script>

<style lang="scss" scoped>
.ol-popup {
  position: fixed;
  background: rgba(255, 255, 255, 0.95);
  border: 2px solid #409eff;
  border-radius: 6px;
  padding: 15px;
  min-width: 220px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  backdrop-filter: blur(2px);
  font-family: system-ui, sans-serif;
  z-index: 1000;

  .ol-popup-closer {
    position: absolute;
    top: 5px;
    right: 10px;
    color: #666;
    text-decoration: none;
    font-size: 20px;
    transition: color 0.2s;

    &:hover {
      color: #409eff;
    }
  }

  #popup-content {
    font-size: 14px;
    color: #333;
    margin-top: 10px;
    font-weight: 500;
  }
}

:deep(.export-image-preview) {
  .el-message-box__content {
    padding: 0;
    line-height: 0;

    img {
      max-width: 80vw;
      max-height: 80vh;
      object-fit: contain;
    }
  }
}
</style>
